/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.gwt.apps.client.program;



import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import net.bioteam.cloud.cluster.ActiveCluster;
import net.bioteam.cloud.cluster.ClusterData;
import net.bioteam.cloud.cluster.ClusterStatus;
import net.bioteam.appweb.gwt.apps.client.StaticHolder;
import net.bioteam.appweb.gwt.apps.client.Util.ApplicationCallBack;
import net.bioteam.appweb.gwt.apps.client.Util.LinkLabel;
import net.bioteam.appweb.gwt.apps.client.Util.UploadItemCallback;
import net.bioteam.appweb.gwt.apps.client.Util.Util;
import net.bioteam.appweb.gwt.apps.clientandserver.Constant;
import net.bioteam.appweb.gwt.apps.clientandserver.user.UserAction;

import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.DateDisplayFormat;
import com.smartgwt.client.types.FormErrorOrientation;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.TitleOrientation;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.events.CloseClientEvent;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.CheckboxItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.IntegerItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.validator.IntegerRangeValidator;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;

public class ClusterSelectionWindow extends Window
{

	TabSet ts;
	ListGrid grid;
	DynamicForm targetForm;
	public ClusterSelectionWindow(DynamicForm f)
	{
		targetForm=f;

		setWidth(550);
		setHeight(400);
		setTitle("Select a cluster to run job");
		setShowMinimizeButton(false);
		setIsModal(true);
		centerInPage();
		//setAutoSize(true);
		setShowCloseButton(true);
		
		addCloseClickHandler(new CloseClickHandler(){

			public void onCloseClick(CloseClientEvent event)
			{
				hide();
				destroy();
			}});
		//setTop(30);
		//setLeft(400);
		//setLayoutMargin(30);
		//setMembersMargin(30);
		
		ts=new TabSet();
		ts.setWidth100();
		ts.setHeight(350);
		
		//------------select grid
		Tab gridTab=new Tab("Select");

		
		VLayout v1=new VLayout();
		v1.setMembersMargin(20);
		
		grid= getActiveClusterGrid();
		grid.setLayoutAlign(Alignment.CENTER);
		v1.addMember(grid);
		
		HLayout hb1=new HLayout();
		hb1.setHeight(30);
		hb1.setWidth(200);
		hb1.setLayoutAlign(Alignment.CENTER);
		IButton bGrid=new IButton("Ok");
		bGrid.addClickHandler(new ClickHandler(){

			public void onClick(ClickEvent event)
			{
				ListGridRecord r=grid.getSelectedRecord();
				if (r==null)
				{
					SC.warn("No record is selected", StaticHolder.dumpB);
					return;
				}
				String clusterid=r.getAttributeAsString("id");

				targetForm.setValue(Constant.progranm_form_cluster_name,clusterid);
				UploadItemCallback.setCallback();
				targetForm.submitForm();

				ClusterSelectionWindow.this.hide();
				ClusterSelectionWindow.this.destroy();
			}});
		IButton cGrid=new IButton("Cancel");
		cGrid.addClickHandler(new ClickHandler(){

			public void onClick(ClickEvent event)
			{
				hide();
				destroy();
			}});
		hb1.addMember(bGrid);
		hb1.addMember(cGrid);
		
		v1.addMember(hb1);
		gridTab.setPane(v1);
		
		//------new
		Canvas v=getNewClusterForm();
		Tab formTab=new Tab("New");
		formTab.setPane(v);
		
		ts.addTab(formTab);
		ts.addTab(gridTab);
		
		addItem(ts);

	}

	public void setActiveCluster(ActiveCluster[] acs)
	{
		if (acs.length==0)
		{
			ts.disableTab(1);
		} 
		
		ListGridRecord records[]=new ListGridRecord[acs.length];
		for (int i=0; i<acs.length; i++)
		{
			ListGridRecord r=new ListGridRecord();
			r.setAttribute("id", acs[i].getId());
			
			int duration=acs[i].getDurationhour()*60;
			r.setAttribute("status", acs[i].getStatus().toString());
			
			if (acs[i].getHead()!=null)
			{
				r.setAttribute("starttime", acs[i].getHead().getStarttime());
				int elapsed=(int)(new Date().getTime()-acs[i].getHead().getStarttime().getTime())/60000;
				int remaining=duration-elapsed;
				r.setAttribute("remaining", remaining);
			} 
			records[i]=r;
		}
		grid.setData(records);
		
	}
	
	public ListGrid getActiveClusterGrid()
	{
		ListGrid grid = new ListGrid();
		grid.setWidth(450);
		grid.setHeight(200);
		grid.setAlternateRecordStyles(true);
		grid.setShowAllRecords(true);
		grid.setShowEmptyMessage(true);
		grid.setEmptyMessage("No Active Cluster");
		grid.setDateFormatter(DateDisplayFormat.TOUSSHORTDATETIME);
		grid.setSelectionType(SelectionStyle.SINGLE);
		grid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
		//grid.setWrapCells(true);
		

		// setAutoFitData(Autofit.HORIZONTAL);
		// setCanRemoveRecords(true);

		ListGridField idField=new ListGridField("id", "ID", 50);
		//idField.setHidden(true);
		
		ListGridField startTimeField = new ListGridField("starttime", "Start Time", 100);
		startTimeField.setType(ListGridFieldType.DATE);
		startTimeField.setDateFormatter(DateDisplayFormat.TOUSSHORTDATETIME);
		startTimeField.setEmptyCellValue("Not Started Yet");

		ListGridField statusField = new ListGridField("status", "Status", 100);
		statusField.setType(ListGridFieldType.TEXT);
		statusField.setCellFormatter(new CellFormatter(){

			public String format(Object value, ListGridRecord record, int rowNum, int colNum)
			{
				if (value.toString().equals(ClusterStatus.BEFORESTART.toString()))
				{
					return "PENDING";
				} else if (value.toString().equals(ClusterStatus.PRESTART.toString()))
				{
					return "CONFIGURING";
				} 
				return value.toString();
			}});

		ListGridField remainingTimeField = new ListGridField("remaining", "Remaing minutes", 150);
		remainingTimeField.setType(ListGridFieldType.TEXT);

		grid.setFields(idField, startTimeField, statusField, remainingTimeField);

		return grid;
	}

	public Canvas getNewClusterForm()
	{
		VLayout v=new VLayout();
		v.setMembersMargin(30);
		
		
		final DynamicForm form = new DynamicForm();
		// form.setBorder("2px solid red");
		
		form.setWidth100();
		form.setHeight(250);
		form.setOverflow(Overflow.AUTO);
		int cellWidth=100;
		form.setColWidths(150, cellWidth);
		//form.setTitleWidth(150);
		//form.setCe
		form.setCellBorder(5);
		form.setNumCols(2);

		form.setShowInlineErrors(true);
		form.setShowErrorText(true);
		form.setErrorOrientation(FormErrorOrientation.TOP);
		form.setRequiredTitleSuffix("<em style='color:red;'>***</em>");

		
		List<FormItem> items=new LinkedList<FormItem>();
		IntegerItem nodes = new IntegerItem();
		nodes.setName("nodes");
		nodes.setTitle("Number of nodes");
		nodes.setRequired(true);
		//nodes.setWidth(100);
		IntegerRangeValidator irv = new IntegerRangeValidator();
		irv.setMin(1);
		irv.setMax(10);
		nodes.setValidators(irv);
		items.add(nodes);
		
		IntegerItem duration=new IntegerItem();
		duration.setName("duration");
		duration.setTitle("Maximal running hours");
		duration.setDefaultValue(1);
		//duration.setWidth(100);
		items.add(duration);
		
		CheckboxItem highIO = new CheckboxItem("highio");
		//highIO.setWidth(150);
		highIO.setDefaultValue(false);
		highIO.setTitle("Run application with high Input/Output");
		highIO.setTitleOrientation(TitleOrientation.LEFT);
		highIO.setShowLabel(false);
		highIO.setLabelAsTitle(true);
		highIO.setShowTitle(true);
		items.add(highIO);
		
		CheckboxItem killifidle = new CheckboxItem("killifidle");
		//killifidle.setWidth(150);
		killifidle.setDefaultValue(true);
		killifidle.setTitle("Kill the cluster if the cluster is idle and even if maximal running hours is not reached");
		killifidle.setTitleOrientation(TitleOrientation.LEFT);
		killifidle.setShowLabel(false);
		killifidle.setLabelAsTitle(true);
		killifidle.setShowTitle(true);
		items.add(killifidle);
		
		final TextItem apps=new TextItem("apps");
		apps.setTitle("volume containing executable and supporting data. Mount point will be "+ClusterData.getAppMountPoint());
		apps.setRequired(true);
		items.add(apps);
		
		//form.setItems(nodes, duration, highIO, killifidle);
		final TextItem blastData=new TextItem("volblast");
		blastData.setTitle("blastable sequence database. Mount point will be "+ClusterData.getBlastMountPoint());
		items.add(blastData);
		
		for(int i=0; i<ClusterData.vollen; i++)
		{
			TextItem vol=new TextItem("vol"+i);
			vol.setTitle("more volume. Mount point will be "+ClusterData.getVolumeMountPoint(i));
//			vol.setWidth(150);
			items.add(vol);
		}
	
		form.setItems(items.toArray(new FormItem[0]));
		
		form.setLayoutAlign(Alignment.CENTER);
		v.addMember(form);
		
		HLayout hb=new HLayout();
		hb.setHeight(30);
		hb.setWidth(300);
		//hb.setBackgroundColor("yellow");
		hb.setLayoutAlign(Alignment.CENTER);
		IButton b=new IButton("Ok");
		b.setWidth(80);
		b.addClickHandler(new ClickHandler(){

			public void onClick(ClickEvent event)
			{
				ApplicationCallBack<ActiveCluster> callback = new ApplicationCallBack<ActiveCluster>()
				{

					public void onFailureAfter(Throwable caught)
					{
						StaticHolder.loadingWindow.hide();
						SC.warn(caught.getMessage(), StaticHolder.dumpB);
					}

					public void onSuccessAfter(ActiveCluster acs)
					{
						String clusterid=String.valueOf(acs.getId());
						
						targetForm.setValue(Constant.progranm_form_cluster_name,clusterid);
						UploadItemCallback.setCallback();
						targetForm.submitForm();
						
						StaticHolder.loadingWindow.hide();
						ClusterSelectionWindow.this.hide();
						ClusterSelectionWindow.this.destroy();
					}

					public void execute()
					{
						ClusterData data=new ClusterData();
						data.nodes=Integer.parseInt(form.getValueAsString("nodes"));
						data.highIO=(Boolean)(form.getField("highio").getValue());
						data.duration=Integer.parseInt(form.getValueAsString("duration"));
						data.killifidle=(Boolean)(form.getField("killifidle").getValue());
						data.blastvolume=form.getValueAsString("volblast");
						data.appvolume=form.getValueAsString("apps");
						for (int i=0; i<ClusterData.vollen; i++)
						{
							data.volumes[i]=form.getValueAsString("vol"+i);
						}
						
						StaticHolder.loadingWindow.show("schedule a cluster for starting...", true);
						UserAction.Util.getInstance().startCluster(data, this);					
					}

				};
				callback.execute();
				
			}});
		
		
		IButton c=new IButton("Cancel");
		c.addClickHandler(new ClickHandler(){

			public void onClick(ClickEvent event)
			{
				ClusterSelectionWindow.this.hide();
				ClusterSelectionWindow.this.destroy();
			}});
		c.setWidth(80);
		hb.addMember(b);
		hb.addMember(c);
		
		LinkLabel label=new LinkLabel("New Cluster Guide");
		label.addClickHandler(new ClickHandler(){

			public void onClick(ClickEvent event)
			{
				Util.open("newcluster.html");
				
			}});
		label.setWidth(140);
		hb.addMember(label);
		v.addMember(hb);
		
//		HTMLPane panel = new HTMLPane();
//		panel.setWidth100();
//		panel.setContentsURL();
//		panel.setHeight(200);
//		panel.setOverflow(Overflow.AUTO);
//		panel.setPageTop(20);
//		v.addMember(panel);

		return v;
	}

}
